import { reactive } from 'vue'

import { ElMessage } from 'element-plus'

import Dialog from '@/components/Dialog/index.vue'
import Drawer from '@/components/Drawer/index.vue'
import Pagination from '@/components/Pagination/index.vue'
import YmTable from '@/components/Table/index.vue'

// import http from '@/utils/request'
import { request as http } from '@/api/service'

import { useConfirm } from '@/utils/common/useConfirm'

import { usePage } from '@/configs/pageObj'
import IBaseObj from '#/index'

export { Dialog as DialogView, Drawer, Pagination, YmTable }

export const commonHandle = () => {
  const state = reactive({
    pageObj: usePage(),
    tableData: [],
    tableLoading: false,
    dialogVisible: false,
    dialogTitle: '',
    isAdd: true,
    saveLoading: false,
  })

  const handleSearch = async (fn: Function, queryForm: IBaseObj) => {
    state.tableLoading = true
    const params = {
      pageSize: state.pageObj.pageSize,
      pageNum: state.pageObj.pageNum,
      ...queryForm,
    }
    try {
      const ret = await fn(params)

      console.log('d', ret)

      const { records, total } = ret

      state.tableData = records || []
      state.pageObj.total = total || 0
    } finally {
      state.tableLoading = false
    }
  }

  const betterHandleSearch = async (options: {
    fn: Function
    queryForm?: IBaseObj
    needPage?: boolean
    otherParams?: any
    needLoading?: boolean
  }) => {
    const defaultOptions = {
      needPage: true,
      needLoading: true,
    }
    const _options = {
      ...defaultOptions,
      ...options,
    }
    const { fn, queryForm, needPage, otherParams, needLoading } = _options
    if (needLoading) {
      state.tableLoading = true
    }

    let params = {
      ...queryForm,
    }
    if (needPage) {
      params = {
        ...params,
        pageSize: state.pageObj.pageSize,
        pageNum: state.pageObj.pageNum,
      }
    }

    try {
      const ret = await fn(params, otherParams)

      if (needPage) {
        const { records, total } = ret

        state.tableData = records || []
        state.pageObj.total = total || 0
      } else {
        state.tableData = ret.data
      }
    } finally {
      state.tableLoading = false
    }
  }

  const handleDelete = (options: {
    url: string
    id: number | string
    message?: string
    success?: Function
    error?: Function
  }) => {
    const message = options.message || '确定删除该信息?'
    useConfirm(
      {
        message,
      },
      async () => {
        const ret = await http({
          url: `${options.url}/${options.id}`,
          method: 'delete',
        })

        if (ret) {
          // 如果有分页并且删除前只有一条数据 返回上一页
          if (state.pageObj) {
            const { total, pageNum } = state.pageObj
            if (state.tableData.length === 1 && pageNum > 1) {
              state.pageObj.pageNum = pageNum - 1
              state.pageObj.total = total - 1
            }
          }
          ElMessage({ message: '删除成功!', type: 'success', duration: 1500 })
          options.success && options.success()
          return true
        }
        ElMessage({ message: '删除失败!', type: 'error', duration: 1500 })
        options.error && options.error(message)
        return false
      }
    )
  }

  /**
   *
   * @param {*} url 删除地址
   * @param {*} id id
   * @param {*} msgObj 双重删除的提示信息
   * @param {*} cb 回调函数
   */
  const handleDoubleDelete = (url: string, id: string | number, msgObj: IBaseObj, cb: Function) => {
    useConfirm(
      {
        message: msgObj?.infoMessage || '确定删除该信息?',
      },
      async () => {
        const res = await http({
          url: `${url}/0/${id}`,
          method: 'delete',
        })
        const { data } = res.data
        if (data) {
          // 可以删除
          // 如果有分页并且删除前只有一条数据 返回上一页
          if (state.pageObj) {
            const { total, pageNum } = state.pageObj
            if (state.tableData.length === 1 && pageNum > 1) {
              state.pageObj.pageNum = pageNum - 1
              state.pageObj.total = total - 1
            }
          }
          ElMessage({ message: '删除成功!', type: 'success', duration: 1500 })
          cb && cb()
          return true
        }
        useConfirm({ message: msgObj?.warnMesssage }, async () => {
          const res = await http({
            url: `${url}/1/${id}`,
            method: 'delete',
          })
          const { data } = res.data
          if (data) {
            ElMessage({ message: '删除成功!', type: 'success', duration: 1500 })
            cb && cb()
          }
        })
      }
    )
  }

  const addAndEditHelper = (title: string) => {
    state.dialogTitle = title
    state.dialogVisible = true
  }

  const handleAdd = (title: string) => {
    addAndEditHelper(title)
    state.isAdd = true
  }

  const handleEdit = (title: string) => {
    addAndEditHelper(title)
    state.isAdd = false
  }

  const handleCancel = (cb?: Function) => {
    state.dialogVisible = false
    cb && cb()
  }

  /**
   *
   * @param valid 验证是否通过
   * @param addApi 新增的api
   * @param updateApi 更新的api
   * @param params 调用api所需的参数
   * @param cb 回调函数
   */
  const handleConfirm = async ({
    valid,
    addApi,
    updateApi,
    params,
    cb,
  }: {
    valid: boolean
    addApi?: Function | any
    updateApi?: Function | any
    params?: IBaseObj
    cb?: Function | any
  }) =>
    // valid: boolean,
    // addApi: Function | any,
    // updateApi: Function | any,
    // params: IBaseObj = {},
    // cb: Function | null = null
    // /* eslint-disable-next-line */
    {
      if (valid) {
        state.saveLoading = true
        try {
          const fn = state.isAdd ? addApi : updateApi
          const data = await fn(params)
          if (data) {
            if (state.isAdd) {
              ElMessage({ message: '添加成功！', type: 'success' })
            } else {
              ElMessage({ message: '编辑成功！', type: 'success' })
            }
            handleClose()
            cb && cb()
          }
        } catch (error) {
          console.log(error)
        } finally {
          state.saveLoading = false
        }
      }
    }

  const handleClose = () => {
    state.dialogVisible = false
  }

  return {
    state,
    handleClose,
    handleAdd,
    handleEdit,
    handleSearch,
    handleDelete,
    handleDoubleDelete,
    handleConfirm,
    betterHandleSearch,
    handleCancel,
  }
}
